package com.fs.uc.core.behavior;

import com.fs.uc.base.domain.*;
import com.fs.uc.base.repo.AdditionalRoleRepository;
import com.fs.uc.base.repo.OrgRepository;
import com.fs.uc.base.repo.PersonRepository;
import com.fs.uc.base.repo.RoleRepository;
import com.fs.uc.core.CacheName;
import io.quarkus.arc.log.LoggerName;
import io.quarkus.cache.Cache;
import io.quarkus.cache.CacheInvalidate;
import io.quarkus.cache.CacheKey;
import io.quarkus.cache.CacheManager;
import io.smallrye.common.constraint.Assert;
import org.jboss.logging.Logger;

import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import javax.transaction.Transactional;
import java.util.List;
import java.util.Optional;

/**
 * @author 崔超
 * 2021/12/31
 */
@ApplicationScoped
@Transactional
class EnterpriseBehaviorImpl implements EnterpriseBehavior {

    @Inject
    OrgRepository orgRepo;
    @Inject
    RoleRepository roleRepo;
    @Inject
    AdditionalRoleRepository additionalRoleRepo;
    @Inject
    PersonRepository personRepo;
    @SuppressWarnings("CdiInjectionPointsInspection")
    @Inject
    CacheManager cacheManager;
    @LoggerName("EnterpriseBehavior")
    Logger log;

    @Override
    public Org create(Long tenantId, Long enterpriseRemoteId, String enterpriseName) {
        Org tenant = orgRepo.getById(tenantId);
        Assert.assertNotNull(tenant);

        Org enterprise = orgRepo.findByRemoteId(enterpriseRemoteId);
        if (enterprise == null) {
            enterprise = new Org();
            enterprise.parent = tenant;
            enterprise.type = OrgType.Enterprise;
            enterprise.remoteId = enterpriseRemoteId;
            enterprise.name = enterpriseName;
            orgRepo.persist(enterprise);
        }
        return enterprise;
    }

    /*
    企业绑定老板，清除新老板的权限缓存，旧老板权限缓存懒得清了
     */
    @CacheInvalidate(cacheName = CacheName.PERSON_PERMISSION)
    @Override
    public void bindBoss(Long enterpriseId, @CacheKey Long personId) {
        Org enterprise = orgRepo.getById(enterpriseId);
        Person person = personRepo.getById(personId);
        assert enterprise.people.contains(person);

        enterprise.leaders.clear();
        enterprise.leaders.add(person);
    }

    /*
    企业入驻园区，清除企业人员权限缓存
     */
    @Override
    public void joinPark(Long enterpriseId, Long parkId) {
        Org enterprise = orgRepo.findByRemoteId(enterpriseId);
        Assert.assertNotNull(enterprise);

        enterprise.parent = orgRepo.getById(parkId);
        orgRepo.persist(enterprise);

        clearPermCache(enterprise.id);
    }

    /*
    企业迁出园区，清除企业人员权限缓存
     */
    @Override
    public void leavePark(Long enterpriseRemoteId) {
        Org enterprise = orgRepo.findByRemoteId(enterpriseRemoteId);
        enterprise.parent = null;
        orgRepo.persist(enterprise);

        clearPermCache(enterprise.id);
    }

    /*
    清除当前组织为xx企业的人的权限缓存
     */
    private void clearPermCache(Long enterpriseId){
        List<Person> people = personRepo.findByCurrentOrg(enterpriseId);
        Optional<Cache> optCache = cacheManager.getCache(CacheName.PERSON_PERMISSION);
        optCache.ifPresent(cache -> {
            for (Person p : people) {
                cache.invalidate(p.id).subscribe().with(
                        suc -> log.info(p.name + "清除权限缓存"),
                        fail -> log.error("清除权限缓存异常：" + fail)
                );
            }
        });
    }
}
